home *** CD-ROM | disk | FTP | other *** search
/ Aminet 32 / Aminet 32 (1999)(Schatztruhe)[!][Aug 1999].iso / Aminet / dev / lang / Python152_Src.lha / Python152_Source / Amiga_Misc / Docs / ARexx_module < prev    next >
Text File  |  1999-01-03  |  19KB  |  493 lines

  1.  
  2. ***************************************************************************
  3.  
  4.                            PYTHON AREXX SUPPORT
  5.  
  6.                          ARexx and ARexxll modules
  7.     
  8.                    by Irmen de Jong - irmen@bigfoot.com
  9.  
  10.                           Last update: 3-Jan-99
  11.  
  12.                                BETA VERSION
  13.  
  14. ***************************************************************************
  15.  
  16. As  this  document  describes  the  BETA VERSION of the ARexx support there
  17. might  be  changes  to what is described below.  This depends on bugs found
  18. and  suggestions  received.   So please:  test the ARexx support and let me
  19. hear any problems/bugs/suggestions (irmen@bigfoot.com).
  20.  
  21. NOTE:  The ARexx support relies on the dos.library support; please read the
  22. documentation on that subject first (Dos_module, python module Dos.py).
  23.  
  24.  
  25. ***************************************************************************
  26.  
  27.                               MODULE: ARexxll
  28.  
  29.                             File: N/A (builtin)
  30.  
  31. ***************************************************************************
  32.  
  33. This module provides the lowlevel ARexx functionality.
  34.  
  35. IMPORTANT:   It  is  DISCOURAGED to use this module directly, use the ARexx
  36. module instead (see below).  This is because it is quite likely that in the
  37. future  some things will be changed in this module.  Furthermore, using the
  38. ARexx module instead is much easier.
  39.  
  40.  
  41. This module defines:
  42.  
  43.   error        - The exception that will be raised when an
  44.           error occurs related to ARexx. ('ARexx.error')
  45.  
  46.   port()    - Function returning a new lowlevel ARexx port object.
  47.           The lowlevel ARexx port object is NOT DOCUMENTED.
  48.           Use a higher-level object from the ARexx module instead.
  49.  
  50.   errorstring()    - Returns string associated with ARexx error number:
  51.           str = ARexxll.errorstring(number)
  52.  
  53.  
  54. ARexx message objects
  55. ~~~~~~~~~~~~~~~~~~~~~
  56. This  module  also implements the ARexx message object.  A message arriving
  57. at  a  ARexx  port  will  be  returned  as  a  ARexx  message  object (type
  58. 'arexxmsg'), which has the following attributes:
  59.  
  60.   reply()    - replies the message with the given results.
  61.           See rc, rc2 and result.  Each message must be replied to!
  62.           Messages which are deleted will be replied automatically,
  63.           if this is not yet done.
  64.   setvar()    - sets ARexx variable for result: setvar('varname','value')
  65.   getvar()    - get value of ARexx variable from caller's environment
  66.  
  67.   wantresult    - does the message require a result string? (int/bool)
  68.   msg        - the message itself (string)
  69.   rc        - result code for reply() (int)
  70.   rc2        - secondary (error) result (string or None)
  71.   result    - result string (string or None)
  72.  
  73. For  details  on  passing  results to the calling application/ARexx script,
  74. refer  to  the  topic  below,  "HOW  RESULTS ARE PASSED BACK TO THE CALLING
  75. APPLICATION".
  76.  
  77.  
  78.  
  79. ***************************************************************************
  80.  
  81.                                MODULE: ARexx
  82.  
  83.                               File: ARexx.py
  84.  
  85. ***************************************************************************
  86.  
  87. This  module  implements  the  Python  ARexx support classes and such.  You
  88. should  use  this module and not ARexxll directly, if your code must remain
  89. compatible with future versions.
  90.  
  91. This module defines:
  92.  
  93.   error        - The exception that will be raised when an
  94.           error occurs related to ARexx. This is the same
  95.           exception as the one in the ARexxll module.
  96.           ('ARexx.error')
  97.  
  98.   errorstring()    - Returns string associated with ARexx error number:
  99.           str = ARexxll.errorstring(number)
  100.  
  101.   RC_OK        - ARexx 'success' return code (0)
  102.   RC_WARN    - ARexx 'warning' return code (5)
  103.   RC_ERROR    - ARexx 'error' return code (10)
  104.   RC_FATAL    - ARexx 'severe failure' return code (20)
  105.  
  106.   port        - class for lowlevel message/ARexx ports. See below.
  107.   privateport    - class for private ARexx ports. See below.
  108.   publicport    - class for public ARexx ports. See below.
  109.  
  110.   host        - class for a full-fledged ARexx host. See below.
  111.   std_help_func    - the default help function used in the host class. See below.
  112.   std_debug_func - a filler and debug function to use with the host class.
  113.            See below.
  114.  
  115.   SendARexxMsg    - utility function to easily send an ARexx message.
  116.                   See Below.
  117.   CallARexxFunc - utility function to easily call an ARexx function.
  118.           See below.
  119.  
  120.   
  121.  
  122. class `port'
  123. ~~~~~~~~~~~~
  124. This  is  the message port abstraction.  Don't create objects of this class
  125. directly!   Instead,  use  one  of  the  derived  classes  `privateport' or
  126. `publicport'.   This  class  is  used  as base class for other port classes
  127. only.
  128.  
  129.  
  130. class `privateport' (derived from `port')
  131. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  132. This  is  the  private  ARexx port abstraction.  The port is a private one,
  133. which  means  it  has no name (and is therefore not public) and can only be
  134. used to send ARexx messages to other ports (which are public).
  135.  
  136. Privateport objects are created as follows:
  137.     p = ARexx.privateport()
  138.  
  139. Attributes of privateport objects:
  140.   port        - The lowlevel ARexx port. DON'T TOUCH.
  141.   signal    - The AmigaDOS signal mask of the port.
  142.  
  143. Methods defined on privateport objects:
  144.   close()
  145.     Close the port.
  146.   send(to,cmd,async=0)
  147.     Send a ARexx message to another port. Currently, all pending
  148.         messages (if any) are removed before the message is sent.
  149.         to = name of port to send message to. (string)
  150.         cmd = command to send (string)
  151.         async = Asynchronous processing? Default=no (0).
  152.     Asynchronous sends will not return a result, but synchronous
  153.     sends do, so you should call this method like:
  154.         result = p.send('REXX','\"return 4*8',0)
  155.     which will put '32' in result. Errors are returned as a 2-tuple
  156.     argument (rc,rc2) to the error exception.
  157.   flush()
  158.     Remove all pending messages (if any) from the port.
  159.   wait()
  160.     private-- behavior not documented for private port objects.
  161.         Don't use it.
  162.   getmsg()
  163.     private-- behavior not documented for private port objects.
  164.         Don't use it.
  165.   setstringmsgs(flag)
  166.     Sets the mode of the command messages sent by this port. If the
  167.     flag is 0 (false), the messages will be parsed by ARexx. If the
  168.     flag is 1 (true), the messages will be treated as a 'string file'.
  169.  
  170.     When the flag is 0 (it is by default), you can execute commands like:
  171.         'test.rexx arg1 arg2 arg3'
  172.     which will call the test.rexx ARexx script with the three arguments.
  173.     You wil have to escape ARexx commands with quotes if you want to
  174.     send a command to ARexx which must be treated as a 'string file':
  175.         '\"SAY 4*8\"'
  176.     
  177.     When the flag is 1 you can no longer execute external commands and
  178.     scripts because the message is treated as a 'string file' - a script
  179.     in itself. You no longer have to quote ARexx commands:
  180.         'SAY 4*8'
  181.  
  182.   settokenizeline(flag)
  183.     Sets the tokenizing mode of the command messages sent by this port.
  184.     If the flag is 0 (false), the command string will not be tokenized.
  185.     If the flag is 1 (true), the command string will be fully tokenized.
  186.  
  187.     When the flag is 0 (it is by default), the arguments will be passed
  188.     to the command as one string. In an ARexx script you can parse them
  189.     yourself using "parse arg ...".
  190.  
  191.     When the flag is 1 the arguments will be fully tokenized and the
  192.     command will receive as many arguments as found in the command string.
  193.     For instance, the string "test.rexx arg1 arg2 arg3" has three arguments.
  194.     In an ARexx script you can get the arguments using the ARG() function;
  195.     "parse arg ..." won't work in this case.
  196.     
  197.  
  198. class `publicport' (derived from `port')
  199. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  200. This  is the public ARexx port abstraction.  The port is public, so it must
  201. have  a  name.  It can be used for receiving ARexx messages and for sending
  202. them.  A publicport is the core of the ARexx host class, see below.
  203.  
  204. Publicport objects are created as follows:
  205.     p = ARexx.publicport()        # default portname PYTHON
  206.     p = ARexx.publicport('FOOBAR')    # portname FOOBAR
  207.  
  208.     When a port with the desired name already exists, sequence numbers
  209.     are automatically appended to the name (PYTHON.1, PYTHON.2 etc).
  210.  
  211.     When you provide a name, it is converted to uppercase.
  212.     If it is not a valid ARexx port name, error will be raised.
  213.     Valid portnames consist of uppercase letters, digits, decimal
  214.     points and underscores, and no other characters.
  215.     
  216.  
  217. Attributes of publicport objects:
  218.   port        - The lowlevel ARexx port. See ARexxll module.
  219.   signal    - The AmigaDOS signal mask of the port.
  220.   name        - The actual port name.
  221.  
  222. Methods defined on publicport objects:
  223.   close()
  224.     Close the port.
  225.   send(to,cmd,async=0)
  226.     See privateport.
  227.   flush()
  228.     See privateport.
  229.   wait()
  230.     Wait until a message arrives. Currently the wait can be aborted
  231.     with a ^C signal. This behavior might change in the future.
  232.   getmsg()
  233.     Receive a message. The message will be removed from the port,
  234.     and it is returned as `message' object (see below).
  235.     Returns None if no messages have arrived, i.e. this operation
  236.         is non-blocking.
  237.   setstringmsgs(flag)
  238.     See privateport.
  239.   settokenizeline(flag)
  240.     See privateport.
  241.  
  242.  
  243.  
  244. class `host' (derived from `publicport')
  245. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  246.  
  247. This   is  the  important  one:   this  class  is  a  complete  ARexx  host
  248. abstraction!   It  contains  all  code  for  setting up the host, receiving
  249. messages,  parsing  the commands and dispatching automatically.  Setting up
  250. your own ARexx host has never been easier.
  251.  
  252. An ARexx host is created as follows:
  253.  
  254.     h = ARexx.host()        # default portname 'PYTHON'
  255.     h = ARexx.host('FOOBAR')    # custom port name
  256.     h = ARexx.host('FOOBAR',cmds)    # custom port name + initial cmds
  257.  
  258.     The port name is used as a public port name. See the notes on
  259.     public port names above, at class `publicport'.
  260.     The third call above supplies an initial list of commands for this
  261.     host. You may also install the list later using the setcommands
  262.     member function.
  263.  
  264. The host has one default command built-in:
  265.  
  266.     HELP COMMAND,STEM/K,VAR/K
  267.  
  268. This  command  works  as  follows.   Without  args  it  returns  the set of
  269. available  commands  like this:  <#commands> <cmd1> ...  <cmdN>.  A COMMAND
  270. argument  gets  help  on  the  specified  command:  the command template is
  271. returned.   The  result is usually put into the RESULT variable.  RC is the
  272. error  code,  RC2  is  the  error string (if any).  Use the VAR argument to
  273. specify a variable yourself to put the result into, instead of RESULT.  Use
  274. the STEM argument to get the result in a slightly different format:
  275.  
  276.     HELP STEM X.
  277.  
  278. gets  the  list  of commands like this:  X.COUNT will contain the number of
  279. result  values (i.e.  the number of commands), where X.1, X.2, X.3...  will
  280. contain the individual results (i.e.  the commands).
  281.  
  282. The  default  help  service  is  implemented  in  the std_help_func command
  283. function, which can be found in the ARexx module.
  284.  
  285.  
  286. Attributes of host objects:
  287.  
  288.   commands    - dictionary of installed ARexx commands. Keys are the
  289.           commands, data is tuple of ArgParser object for the
  290.           template and the command function to call.
  291.   cmderror    - error string for calling app when command is unknown.
  292.           Default is 'Unknown command'.
  293.   catch        - will exceptions in ARexx commands be catched or not (0/1)
  294.           Default is 0; don't catch. Beware: the calling app may
  295.           freeze if your ARexx command raises an exception (because
  296.           the message is not replied to). Just exit Python and
  297.           all will be fine.
  298.   name        - see publicport class
  299.   port        - see publicport class
  300.   signal    - see publicport class
  301.  
  302. Methods defined on host objects:
  303.  
  304.   close()
  305.     Close the ARexx port (shutdown the host)
  306.     You can also just delete the host object.
  307.  
  308.   setcommands(cmdlist)
  309.     Specify a list of commands for this host.
  310.     cmdlist = list of commands (4-tuple: command, template,
  311.     defaults, function. See setcommand.)
  312.  
  313.   setcommand(cmd,templ,defaults,func)
  314.     Install a single command for this host
  315.     cmd = the command, for instance 'HELP'. Uppercase please.
  316.     templ = the argument template, ReadArg() format, for instance
  317.             'COMMAND,STEM/K,VAR/K,AMOUNT/N'. See also the ArgParser
  318.             class from the `Dos' module. You can also specify None,
  319.         then no argument parser will be associated with this
  320.             command. This means that all arguments are passed straight
  321.         to the command function. This can be used for creating ARexx
  322.         commands with non-ReadArg() style arguments.
  323.         Use the empty string if you want the command to have NO
  324.             arguments! This is different than None! 
  325.     defaults = either None or a dictionary which specifies for some
  326.                keywords in the template what the default values are, if
  327.                the user doesn't specify them. Example: {'AMOUNT': 10}.
  328.                If you use None, some sensible values are chosen,
  329.                depending on the types of the keywords.
  330.     func = the command function which is associated with this command.
  331.            See the topic, "HOW TO IMPLEMENT COMMAND FUNCTIONS".
  332.  
  333.   setdefaults(cmd,defaults)
  334.     Install (new) default values for a command's argument template
  335.     cmd = the command
  336.     defaults = see above (setcommand)
  337.  
  338.   defaults(cmd)
  339.     Query default values for a command's argument template
  340.     cmd = the command
  341.  
  342.   catchExceptions(flag)
  343.     flag= int/boolean argument:
  344.      0 : don't catch exceptions. When an exception occurs in an
  345.          ARexx command function, your program aborts (=default).
  346.      1 : catch exceptions. When an exception occurs in an Arexx command
  347.          function, it will be passed back to the calling application as
  348.          an error string, while your python program continues.
  349.   dispatch()
  350.     When a message is present, process it. The arguments will
  351.     be parsed according  to the command's template and the
  352.     correct command function is executed. The following
  353.     return codes are defined:
  354.       -1 : there were no messages
  355.        0 : (false) a command function returned false, i.e. it failed
  356.        1 : message processed ok, command function executed ok
  357.  
  358.   flush()
  359.     Process each pending message untill there are none left.
  360.   run()
  361.     Enter a wait/dispatch loop until one of the command
  362.     functions returns false (0) or an error occurs.
  363.  
  364.   setstringmsgs(flag)
  365.     Inherited from publicport.
  366.  
  367.   settokenizeline(flag)
  368.     Inherited from publicport.
  369.  
  370.  
  371.  
  372. HOW TO IMPLEMENT COMMAND FUNCTIONS
  373. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  374. They must be declared like this:
  375.     def cmd_func(host,msg,cmd,args)
  376. where
  377.     host    = ARexx host object invoking this function
  378.     msg    = the ARexx message which was received
  379.     cmd    = the command which was called (string)
  380.     args    = dictionary of arguments and their valued provided for
  381.           this command. See also ArgParser class from `Dos' module.
  382.           Optionally, this is a regular string which contains
  383.           the argument line unchanged. This is the case when the
  384.           command has been added without an argument template.
  385.           See the setcommand memberfunction of the host class.
  386.  
  387. They  must  return  either 1 (true) or 0 (false).  0 indicates an error and
  388. will  cause  the  `run' memberfunction of your ARexx host to abort (because
  389. `dispatch' returns 0).
  390.  
  391.  
  392. HOW RESULTS ARE PASSED BACK TO THE CALLING APPLICATION
  393. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  394. Lets call the message you've received from your ARexx host `M'.  First, you
  395. might  want to check the value of M.wantresult.  If it is zero (false), the
  396. calling  app  is not expecting any results (if it's an ARexx script, it has
  397. not  set  `options  results').  If it is non-zero (true) the calling app is
  398. possibly expecting a result value (Arexx script has set `options results').
  399. Ofcourse  your  function  should  eventually decide if it needs to return a
  400. result value.
  401.  
  402. M.rc  must  be  set  to  the  appropriate  ARexx return code (one of RC_OK,
  403. RC_WARN, RC_ERROR and RC_FATAL).  By default it is set to RC_OK (0).
  404.  
  405. If  M.rc  is  RC_OK  (0), put the result string in M.result.  M.rc2 remains
  406. unchanged  (None).   If  you  must  return  results in other variables, use
  407. M.setvar  to  set them.  See the implementation of the default HELP command
  408. for  how  this  can  be  done (the user can ask for the result to be put in
  409. another variable, instead of RESULT).
  410.  
  411. If  M.rc  is  not  RC_OK  (0),  you should put a secondary result string in
  412. M.rc2.  Usually this will be a string describing what went wrong.  M.result
  413. does  not  need  to  have  a  value  in this case.  Other variables (set by
  414. M.setvar) can still have a result value.
  415.  
  416. When  you're  done, you must reply the message.  This can be done by either
  417. deleting  the  message  or  (better) by invoking M.reply() explicitly.  The
  418. latter is not necessary but then you must make sure M gets deleted on time,
  419. otherwise the message is not replied to, and the calling app will freeze.
  420.  
  421.  
  422. HOW THE CALLING APPLICATION GETS RESULTS BACK FROM A CALL
  423. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  424. If  you require results and you are using an ARexx script, you should issue
  425. the `options results' command first.  The following result variables exist:
  426.  
  427.   RC    - primary return code
  428.   RC2    - secondary result (error)string, if RC != 0
  429.   RESULT - regular result value.
  430.  
  431. If  RC is 0, all went well and RESULT will contain the result, if any.  RC2
  432. has no value in this case.
  433.  
  434. If  RC  is  not  0, there was some error and RC2 will contain the secondary
  435. result string, this is usually a string describing what went wrong.  RESULT
  436. has no value in this case.
  437.  
  438. Sometimes it is possible to get the results in other variables than RESULT.
  439. This  depends  on  the  function  you're calling.  The documentation of the
  440. function   should  say  exactly  what  to  expect  from  it.   The  default
  441. implementation  of  the HELP command is such a function:  you can specify a
  442. variable yourself instead of relying on RESULT.
  443.  
  444.  
  445. The `std_help_func' utility function
  446. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  447. This is the default command function connected with the `HELP' command.  It
  448. might be a good example of implementing a command function.  You might want
  449. to  write  your  own help function, for example to give more extensive help
  450. descriptions.   Just  use  the  `setcommand'  memberfunction to replace the
  451. existing `HELP' command.  Do NOT change the source code of the default help
  452. function!!! (It is part of the standard library, remember!)
  453.  
  454. The `std_debug_func' utility function
  455. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  456. When  you  use  this  function as a command function for a command, it will
  457. print  out  some  debug  information  to  the screen and reply the command.
  458. Useful for testing or for unfinished commands.
  459.  
  460.  
  461.  
  462. Miscellaneous utility functions
  463. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  464.  
  465. SendARexxMsg:
  466.     You have to create at least a privateport to be able to send ARexx
  467.     messages. This function is a shortcut, it will create a temporary
  468.     privateport for you and send your message. You use it like this:
  469.  
  470.         result = SendARexxMsg( PORTNAME, MESSAGE)
  471.  
  472.     For instance,
  473.         print ARexx.SendARexxMsg('REXX','"return 4*9')
  474.     will print 36.
  475.  
  476. CallARexxFunc:
  477.     Like sending ARexx messages, you need a port to be able to call
  478.     ARexx functions (in ARexx extension libraries for instance). This
  479.     function is a handy shortcut. You use it like this:
  480.  
  481.         result = CallARexxFunc( FUNCTION, ARGUMENTS... )
  482.  
  483.     For instance,
  484.         print ARexx.CallARexxFunc('RxTr_MakePath', 'hd0:devs', 'monitors')
  485.     will print hd0:devs/monitors. (Provided you have correctly installed
  486.     and initialized rexxtricks.library with ARexx).
  487.  
  488.     What this call did under water is building the string
  489.         "Return RxTr_MakePath('hd0:devs','monitors')"
  490.     and sending this string to the REXX port using SendARexxMsg above.
  491.  
  492.  
  493.